package com.wika.basics.widget

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader.TileMode
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.Log
import androidx.appcompat.widget.AppCompatImageView
import com.wika.basics.R


/**
 *@Description:
 *@Date: 2024/7/18 14:28
 *@Author: WangWeiShuo
 */
class RoundImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
): AppCompatImageView(context,  attrs, defStyleAttr) {
    val TYPE_NONE = 0
    /**
     * 圆形
     */
    val TYPE_CIRCLE = 1
    /**
     * 圆角矩形
     */
    val TYPE_ROUNDED_RECT = 2

    private val DEFAULT_TYPE = TYPE_NONE
    private val DEFAULT_BORDER_COLOR = Color.TRANSPARENT
    private val DEFAULT_BORDER_WIDTH = 0
    private val DEFAULT_RECT_ROUND_RADIUS = 0

    private var mType = 0
    private var mBorderColor = 0
    private var mBorderWidth = 0
    private var mRectRoundRadius = 0

    private val mPaintBitmap = Paint(Paint.ANTI_ALIAS_FLAG)
    private val mPaintBorder = Paint(Paint.ANTI_ALIAS_FLAG)

    private val mRectBorder = RectF()
    private val mRectBitmap = RectF()

    private var mRawBitmap: Bitmap? = null
    private var mShader: BitmapShader? = null
    private val mMatrix: Matrix = Matrix()

    init {
        initAttrs(context, attrs)
    }

    fun initAttrs(context: Context, attrs: AttributeSet?) {
        //取xml文件中设定的参数
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView)
        mType = typedArray.getInt(R.styleable.RoundImageView_type, DEFAULT_TYPE)
        mBorderColor = typedArray.getColor(R.styleable.RoundImageView_borderColor, DEFAULT_BORDER_COLOR)
        mBorderWidth = typedArray.getDimensionPixelSize(
            R.styleable.RoundImageView_borderWidth,
            dip2px(DEFAULT_BORDER_WIDTH)
        )
        mRectRoundRadius = typedArray.getDimensionPixelSize(
            R.styleable.RoundImageView_rectRoundRadius,
            dip2px(DEFAULT_RECT_ROUND_RADIUS)
        )
        typedArray.recycle()
    }

    override fun onDraw(canvas: Canvas) {
        Log.e("TAG", "getBitmap: drawable = $drawable", )
        val rawBitmap = getBitmap(drawable)
        if (rawBitmap != null && mType != TYPE_NONE) {
            val viewWidth = width
            val viewHeight = height
            val viewMinSize = Math.min(viewWidth, viewHeight)
            val dstWidth = (if (mType == TYPE_CIRCLE) viewMinSize else viewWidth).toFloat()
            val dstHeight = (if (mType == TYPE_CIRCLE) viewMinSize else viewHeight).toFloat()
            val halfBorderWidth = mBorderWidth / 2.0f
            val doubleBorderWidth = (mBorderWidth * 2).toFloat()
            if (mShader == null || rawBitmap != mRawBitmap) {
                mRawBitmap = rawBitmap
                mShader = BitmapShader(mRawBitmap!!, TileMode.CLAMP, TileMode.CLAMP)
            }
            if (mShader != null) {
                mMatrix.setScale(
                    (dstWidth - doubleBorderWidth) / rawBitmap.width,
                    (dstHeight - doubleBorderWidth) / rawBitmap.height
                )
                mShader!!.setLocalMatrix(mMatrix)
            }
            mPaintBitmap.shader = mShader
            mPaintBorder.style = Paint.Style.STROKE
            mPaintBorder.strokeWidth = mBorderWidth.toFloat()
            mPaintBorder.color = if (mBorderWidth > 0) mBorderColor else Color.TRANSPARENT
            if (mType == TYPE_CIRCLE) {
                val radius = viewMinSize / 2.0f
                canvas.drawCircle(radius, radius, radius - halfBorderWidth, mPaintBorder)
                canvas.translate(mBorderWidth.toFloat(), mBorderWidth.toFloat())
                canvas.drawCircle(
                    radius - mBorderWidth,
                    radius - mBorderWidth,
                    radius - mBorderWidth,
                    mPaintBitmap
                )
            } else if (mType == TYPE_ROUNDED_RECT) {
                mRectBorder[halfBorderWidth, halfBorderWidth, dstWidth - halfBorderWidth] =
                    dstHeight - halfBorderWidth
                mRectBitmap[0.0f, 0.0f, dstWidth - doubleBorderWidth] =
                    dstHeight - doubleBorderWidth
                val borderRadius =
                    if (mRectRoundRadius - halfBorderWidth > 0.0f) mRectRoundRadius - halfBorderWidth else 0.0f
                val bitmapRadius =
                    if (mRectRoundRadius - mBorderWidth > 0.0f) (mRectRoundRadius - mBorderWidth).toFloat() else 0.0f
                canvas.drawRoundRect(mRectBorder, borderRadius, borderRadius, mPaintBorder)
                canvas.translate(mBorderWidth.toFloat(), mBorderWidth.toFloat())
                canvas.drawRoundRect(mRectBitmap, bitmapRadius, bitmapRadius, mPaintBitmap)
            }
        } else {
            super.onDraw(canvas)
        }
    }

    private fun dip2px(dipVal: Int): Int {
        val scale = resources.displayMetrics.density
        return (dipVal * scale + 0.5f).toInt()
    }

    private fun getBitmap(drawable: Drawable): Bitmap? {
        return if (drawable is BitmapDrawable) {
            drawable.bitmap
        } else if (drawable is ColorDrawable) {
            val rect = drawable.getBounds()
            val width = rect.right - rect.left
            val height = rect.bottom - rect.top
            val color = drawable.color
            val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            canvas.drawARGB(
                Color.alpha(color),
                Color.red(color),
                Color.green(color),
                Color.blue(color)
            )
            bitmap
        } else {
            null
        }
    }
}